package journalarray;

import java.util.Arrays;
import java.util.Date;

/**
 * @author Евгений
 */
public class ArrayJournal implements Journal {
    private Record [] db;
    private int size = 0;
    private final int defSz = 10;
    
    /**
     * Make new empty journal
     */
    public ArrayJournal() {
        db = new Record [defSz];
        size = 0;
    }
    
    /**
     * Copy all object from old journal j
     * Copy constructor
     * @param j old journal
     */
    public ArrayJournal(Journal j) {
        size = j.size();
        db = new Record [size];
        
        for (int i = 0; i < size; i++) {
            Record r = j.get(i);
            db[i] = new Record(r.getTime(),r.getImportance(),r.getSource(),r.getMessage());
        }
    }
    
    private void upSize() {
        int newSize = (size * 3) / 2 + 1;
        Record [] newDb = new Record [newSize];
        
        for (int i = 0; i < size; i++) {
            newDb[i] = db[i];
        }
        
        db = newDb;
    }
    
    @Override
    public void add(Record r) {
        if (size + 1 > db.length) upSize();
        
        size++;
        db[size - 1] = r;
        
    }

    @Override
    public void add(Journal j) {
        int jSz = j.size();
       
        for (int i = 0; i < jSz; i++) {
            if (size + 1 > db.length) upSize();
            db[size++] = j.get(i);
        }
    }

    @Override
    public void remove(Record r) {
        outer:
        for (int i = 0; i < size; i++) {
            if (db[i].equals(r)) {
                size--;
                for (int j = i; j < size - 1; j++) {
                    db[j] = db[j + 1];
                }
                break outer;
                
            }
        }
        
    }
    
    /**
     * Return record with entered index
     * @param index index of the record in database
     * @return record with index
     * @exception ArrayIndexOutOfBoundsException if index < 0 or index >= size
     */
    @Override
    public Record get(int index) {
        if (index >= size || index < 0) {
            throw new ArrayIndexOutOfBoundsException();
        }
        
        if (index < size)
            return db[index];
        
        return null;
    }

    @Override
    public void set(int index, Record record) {
        if (index < size) {
            db[index] = record;
        }else {
            return;
        }
    }

    @Override
    public void insert(int index, Record record) {
        if (index < 0) return;
        if (size + 1 > db.length) upSize();
        
        size++;
        
        for (int i = size - 1; i >= index; i--) {
            db[i] = db[i - 1];
        }
        
        db[index] = record;
    }

    @Override
    public void remove(int index) {
        if (index < 0) return;
        
        for (int i = index; i < size; i++) {
            db[i] = db[i + 1];
        }
        
        size--;
    }

    @Override
    public void remove(int fromIndex, int toIndex) {
        if (fromIndex > toIndex || fromIndex <0 || toIndex < 0 || toIndex >= size) return;
        
        int k = ++toIndex - fromIndex;
        
        for (int i = toIndex; i < size; i++) {
            db[fromIndex++] = db[i];
        }
        
        size -= k;
    }

    @Override
    public void removeAll() {
        size = 0;
        db = new Record [defSz];
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public Journal filter(String s) {
        Journal j = new ArrayJournal(); 
        
        for (int i = 0; i < size; i++) {
            String toString = db[i].toString();
            if (toString.indexOf(s) >= 0) {
                j.add(db[i]);
            }
        }
        
        return j;
    }

    @Override
    public Journal filter(Date fromDate, Date toDate) {
        Journal j = new ArrayJournal();
        
        for (int i = 0; i < size; i++) {
            Date date = db[i].getTime();
            if (date.after(fromDate) && date.before(toDate)) {
                j.add(db[i]);
            }
        }
        
        return j;
    }

    @Override
    public void sortByDate() {
        Arrays.sort(db,0,size,new SortedByDate());
    }

    @Override
    public void sortByImportanceDate() {
        Arrays.sort(db,0,size,new SortByImportanceDate());
    }

    @Override
    public void sortByImportanceSourceDate() {
        Arrays.sort(db, 0, size, new SortByImportanceSourceDate());
    }

    @Override
    public void sortBySourceDate() {
        Arrays.sort(db, 0, size, new SortBySourceDate());
    }

    @Override
    public void printRecords() {
        for (int i = 0; i < size; i++) {
            System.out.println(db[i].toString());
        }
    }
    
    
}
